home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1989 / 02 / pwcomm1 / ttycls.c < prev    next >
Text File  |  1988-12-04  |  8KB  |  326 lines

  1. /*
  2.  * TTYCLS module
  3.  *
  4.  * Written by Bill Hall
  5.  * 3665  Benton Street, #66
  6.  * Santa Clara, CA 95051
  7.  *
  8.  * This file supports a teletype style window in either Microsoft
  9.  * windows or Presentation Manager.
  10.  *
  11.  * For an example of its use, see the source code for WINAUX
  12.  * or PMAUX.
  13.  *
  14.  * If being used in a Windows program, be sure to define WINDOWS
  15.  */
  16.  
  17. #ifdef WINDOWS
  18. #define NOCOMM        /* stops a bunch of unneeded level 3 warnings */
  19. #include <windows.h>
  20. #else
  21. #define INCL_PM
  22. #include <os2.h>
  23. extern HAB hAB;        /* these should be defined in the main program */
  24. extern HHEAP hHeap;
  25. #endif
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <memory.h>
  29. #include "ascii.h"
  30. #include "ttycls.h"
  31.  
  32. /* local functions */
  33. static void NEAR DoLF(PTTYWND pTTYWnd);
  34. static void NEAR DoCR(PTTYWND pTTYWnd);
  35. static void NEAR DoBS(PTTYWND pTTYWnd);
  36. static void NEAR DoTab(PTTYWND pTTYWnd);
  37.  
  38. /* 
  39.  * Called at create window time.  Creates a text buffer based
  40.  * on the passed in width, height, and the character width and height.
  41.  * Other parameters such as wrap, character mask, etc. are also set.
  42.  */
  43. InitTTYWindow(pTTYWnd,left,top,width,height,charwidth,charheight,LFonCR,CRonLF,
  44.                 wrap,mask)
  45. PTTYWND pTTYWnd;
  46. short left, top, width, height, charwidth, charheight;
  47. BOOL LFonCR, CRonLF, wrap;
  48. BYTE mask; 
  49. {
  50.     
  51.     int bufsize;
  52.  
  53.     pTTYWnd->Left = left;
  54.     pTTYWnd->Top = top;
  55.     pTTYWnd->Width = width;
  56.     pTTYWnd->Height = height;
  57.     pTTYWnd->CWidth = charwidth;
  58.     pTTYWnd->CHeight = charheight;
  59.     pTTYWnd->MaxLines = height / charheight;
  60.     pTTYWnd->MaxCols = width / charwidth;
  61.     pTTYWnd->MaxLineLength = pTTYWnd->MaxCols + 1;
  62.     bufsize = pTTYWnd->MaxLines * pTTYWnd->MaxLineLength;
  63.  
  64.   /* allocate space for the display characters */
  65.   /* if allocation successful, initialize the remaining tty data */
  66.  
  67. #ifdef WINDOWS
  68.     if (pTTYWnd->hVidBuf = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, bufsize)) {
  69.     pTTYWnd->pVidBuf = LocalLock(pTTYWnd->hVidBuf); /* lock the buffer */
  70.         pTTYWnd->Pos.y = (pTTYWnd->MaxLines - 1) * charheight - 1;
  71. #else
  72.     if (pTTYWnd->pVidBuf = WinAllocMem(hHeap, bufsize)) {
  73.     memset(pTTYWnd->pVidBuf, NUL, bufsize);
  74.         pTTYWnd->Pos.y = 1;
  75. #endif
  76.         pTTYWnd->Pos.x = 0;
  77.     pTTYWnd->oCurrentLine = pTTYWnd->CurLineOffset = 0;
  78.     pTTYWnd->oVidLastLine = (pTTYWnd->MaxLines-1) * pTTYWnd->MaxLineLength;
  79.     pTTYWnd->LFonCR = LFonCR;
  80.     pTTYWnd->CRonLF = CRonLF;
  81.         pTTYWnd->Wrap = wrap;
  82.     pTTYWnd->ebitmask = mask;
  83.       return TRUE;
  84.     }
  85.     return FALSE;
  86. }
  87.  
  88. /* display the characters contained in str */
  89. int NEAR TTYDisplay(PTTYWND pTTYWnd, short len, BYTE *str)
  90. {
  91.  
  92.     HPS hPS;
  93.     register BYTE *ptr;
  94.     register short ctr;
  95.     short toff, txpos;
  96.     BYTE *tbuf;
  97.  
  98.     short cols = pTTYWnd->MaxCols;
  99.     short cwidth = pTTYWnd->CWidth;
  100.     BYTE mask = pTTYWnd->ebitmask;
  101.   
  102.     while (len) {
  103.        ptr = str;
  104.     ctr = 0;
  105.      txpos = (short)pTTYWnd->Pos.x;
  106.      tbuf = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  107.     toff = pTTYWnd->CurLineOffset;
  108.  
  109.     while((*ptr &= mask) >= SP) {
  110.         if ((len) && (toff < cols)) {
  111.         ctr += 1;
  112.         *(tbuf + toff++) = *ptr++;
  113.         txpos += cwidth;
  114.         len -= 1;
  115.         }
  116.         else
  117.         break;
  118.     }
  119.     if (ctr) {
  120. #ifdef WINDOWS
  121.         hPS = GetDC(pTTYWnd->hWnd);
  122.         TextOut(hPS, pTTYWnd->Pos.x, pTTYWnd->Pos.y, (LPSTR)str, ctr);
  123.         ReleaseDC(pTTYWnd->hWnd, hPS);
  124. #else
  125.         hPS = WinGetPS(pTTYWnd->hWnd);
  126.         GpiSetBackMix(hPS, BM_OVERPAINT);
  127.         GpiCharStringAt(hPS,(PPOINTL)&pTTYWnd->Pos,(LONG)ctr,(PCH)str);
  128.         GpiRestorePS(hPS, -1L);
  129.         WinReleasePS (hPS);
  130. #endif
  131.         if (toff < cols) {
  132.             pTTYWnd->CurLineOffset = toff;
  133. #ifdef WINDOWS
  134.             pTTYWnd->Pos.x = txpos;
  135. #else
  136.             pTTYWnd->Pos.x = (LONG)txpos;
  137. #endif
  138.         }
  139.         else
  140.         if (pTTYWnd->Wrap) {
  141.             DoCR(pTTYWnd);
  142.             DoLF(pTTYWnd);
  143.             }        
  144.     }
  145.     while ((*ptr &= mask) < SP) {
  146.         if (len) {
  147.         switch(*ptr) {
  148.             case BEL:
  149. #ifdef WINDOWS
  150.             MessageBeep(0);
  151. #else
  152.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  153. #endif
  154.             break;
  155.             case HT:
  156.             DoTab(pTTYWnd);
  157.             break;            
  158.             case CR:
  159.             DoCR(pTTYWnd);
  160.             if (pTTYWnd->LFonCR)
  161.                 DoLF(pTTYWnd);
  162.             break;
  163.             case LF:
  164.             if (pTTYWnd->CRonLF)
  165.                 DoCR(pTTYWnd);
  166.             DoLF(pTTYWnd);
  167.             break;
  168.             case BS:
  169.             DoBS(pTTYWnd);
  170.             break;
  171.         }
  172.         len -= 1;
  173.         ptr++;
  174.         }
  175.         else
  176.         break;
  177.     }
  178.         str = ptr;
  179.     }
  180.     return (len);
  181. }
  182.  
  183. /* perform a carriage return */
  184. static void NEAR DoCR(PTTYWND pTTYWnd)
  185. {
  186.     pTTYWnd->CurLineOffset = 0;
  187.     pTTYWnd->Pos.x = 0;
  188. }
  189.  
  190. /* perform a line feed */
  191. static void NEAR DoLF(PTTYWND pTTYWnd)
  192. {
  193.     BYTE *pCurr;
  194.     short offset, cols;
  195.     int i;
  196.     HWND hWnd = pTTYWnd->hWnd;
  197.     cols = pTTYWnd->MaxCols;
  198.  
  199.     if ((pTTYWnd->oCurrentLine+=pTTYWnd->MaxLineLength) > pTTYWnd->oVidLastLine)
  200.     pTTYWnd->oCurrentLine = 0;
  201.     pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  202.     offset = pTTYWnd->CurLineOffset;
  203.  
  204.     for (i = 0; i < offset; i++)
  205.     *(pCurr + i) = SP;
  206.     for (i = offset; i < cols; i++)
  207.     *(pCurr + i) = NUL;
  208.  
  209. #ifdef WINDOWS
  210.     ScrollWindow(hWnd,0,-pTTYWnd->CHeight,(LPRECT)NULL,(LPRECT)NULL);
  211.     UpdateWindow(hWnd);
  212. #else
  213.     WinScrollWindow(hWnd,0,pTTYWnd->CHeight,
  214.                 NULL,NULL,NULL,NULL,SW_INVALIDATERGN);
  215.     WinUpdateWindow(hWnd);    
  216. #endif
  217. }
  218.  
  219. /* perform a backspace */
  220. static void NEAR DoBS(PTTYWND pTTYWnd)
  221. {
  222.     if (pTTYWnd->CurLineOffset > 0) {
  223. #ifdef WINDOWS
  224.     pTTYWnd->Pos.x -= pTTYWnd->CWidth;
  225. #else
  226.     pTTYWnd->Pos.x -= (LONG)pTTYWnd->CWidth;
  227. #endif
  228.     pTTYWnd->CurLineOffset -= 1;
  229.     }
  230. }
  231.  
  232. /* Horizontal tab */
  233. static void NEAR DoTab(pTTYWnd)
  234. PTTYWND pTTYWnd;
  235. {
  236.  
  237.     short curoffset, xpos, ypos, cols, cwidth;
  238.     BYTE *pCurr;
  239. #ifdef WINDOWS
  240.     RECT myrect;
  241. #else
  242.     RECTL myrect;
  243. #endif
  244.     cols = pTTYWnd->MaxCols;
  245.     curoffset = pTTYWnd->CurLineOffset;
  246.     cwidth = pTTYWnd->CWidth;
  247.  
  248.     if (curoffset < (cols - 1)) {
  249.         xpos = (short)pTTYWnd->Pos.x;        /* initialize variables */
  250.         ypos = (short)pTTYWnd->Pos.y;
  251.         pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
  252.         do {
  253.         if (*(pCurr + curoffset) == NUL)  /* if null, replace with space */
  254.             *(pCurr + curoffset) = SP;
  255.         curoffset += 1;        /* update offsets */
  256.         xpos += cwidth;
  257.         } while ((curoffset % 8 != 0) && (curoffset < (cols - 1)));
  258.  
  259.     /* now invalidate the part of the screen affected */
  260. #ifdef WINDOWS
  261.     SetRect((LPRECT)&myrect, xpos, ypos, pTTYWnd->Width, pTTYWnd->Height);
  262.     InvalidateRect(pTTYWnd->hWnd, (LPRECT)&myrect, TRUE);
  263. #else
  264.     WinSetRect(hAB,&myrect,xpos,ypos,pTTYWnd->Width,ypos+pTTYWnd->CHeight);
  265.     WinInvalidateRect(pTTYWnd->hWnd, &myrect, TRUE);
  266. #endif
  267.     /* finally, reset the tty window variables */
  268.         pTTYWnd->Pos.x = xpos;
  269.         pTTYWnd->CurLineOffset = curoffset;
  270.     }
  271. }
  272.  
  273. /* repaint the window */
  274. void NEAR TTYWndPaint(PTTYWND pTTYWnd, HPS hPS, short top, short bottom)
  275. {
  276.  
  277. #ifdef WINDOWS
  278.     POINT pt;
  279.     short wtop;
  280. #else
  281.     POINTL pt;
  282. #endif
  283.     BYTE *lineptr;
  284.     BYTE *pBuf, *pEnd;
  285.     short lines, length;
  286.     short cheight;
  287.     int i;
  288.  
  289. #ifndef WINDOWS
  290.     GpiErase (hPS);
  291. #endif
  292.     pt.x = 0;
  293.     pBuf = pTTYWnd->pVidBuf;
  294.     pEnd = pBuf + pTTYWnd->oVidLastLine;
  295.  
  296.     lineptr = pBuf + pTTYWnd->oCurrentLine;
  297.     pt.y = pTTYWnd->Pos.y;
  298.  
  299.     length = pTTYWnd->MaxLineLength;
  300.     cheight = pTTYWnd->CHeight;
  301. #ifdef WINDOWS
  302.     wtop = pTTYWnd->Height - top;
  303.     lines = wtop / cheight;
  304.     if (wtop % cheight)
  305.     lines += 1;
  306.     lines = min(pTTYWnd->MaxLines, lines);
  307. #else
  308.     lines = top / cheight;
  309.     if (top % cheight)
  310.     lines += 1;
  311.     lines = min(pTTYWnd->MaxLines, lines);
  312. #endif
  313.  
  314.     for (i = 0; i < lines; i++) {
  315. #ifdef WINDOWS
  316.         TextOut(hPS, pt.x, pt.y, (LPSTR)lineptr, strlen(lineptr));
  317.     pt.y -= cheight;
  318. #else
  319.         GpiCharStringAt(hPS,&pt,(LONG)strlen(lineptr),(PCH)lineptr);
  320.     pt.y += (LONG)cheight;
  321. #endif
  322.         if ((lineptr -= length) < pBuf)
  323.         lineptr = pEnd;
  324.     }
  325. }
  326.